package com.gitee.wsl.data.pool.sample

import com.gitee.wsl.data.pool.Pool


/** @author zeganstyl */
class UsedPool<T>(
    val create: () -> T,
    val reset: ((instance: T) -> Unit)?=null
): Pool<T> {

    override val capacity: Int get() = free.size

    override fun releaseAll(instances: List<T>) {
        free.addAll(instances.toList())
        used.removeAll(instances.toSet())
    }

    val free = ArrayList<T>()

    val used = ArrayList<T>()

    override fun acquire(): T {
        val obj = if (free.isNotEmpty()) {
            val instance = free[0]
            free.remove(instance)
            instance
        } else {
            create()
        }
        reset?.invoke(obj)
        used.add(obj)
        return obj
    }

    inline fun getOrCreate(create: () -> T): T {
        val obj = if (free.isNotEmpty()) {
            val instance = free[0]
            free.remove(instance)
            instance
        } else {
            create()
        }
        reset?.invoke(obj)
        used.add(obj)
        return obj
    }

    override fun release(instance: T):Boolean {
        free.add(instance)
        used.remove(instance)
        return true
    }

    override fun dispose() {
        free.clear()
        used.clear()
    }
}

fun <T> Pool.Companion.used(create: () -> T,  reset: ((instance: T) -> Unit)? = null)
     = UsedPool(create,reset)